package com.myebills.ebpsfrontend.cust.controller;

public class EbppxTransformer
{
	private String timeStamp;
	private String hardKey;
	private int transform=0;

    //NOTE: list 0 shows all the acceptable characters for String to encrypt
	private final char[] list0= new char[] { 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','`','1','2','3','4','5','6','7','8','9','0','-','+','~','!','@','#','$','%','^','&','*','(',')','_','+','[',']','\\','{','}','|',';','\'',':','\"',',','.','/','<','>','?' };

	private final char[] list1= new char[] { '~','`','1','q','a','z','!','Q','A','Z','2','w','s','x','@','W','S','X','3','e','d','c','#','E','D','C','4','r','f','v','$','R','F','V','5','t','g','b','%','T','G','B','6','y','h','n','^','Y','H','N','7','u','j','m','&','U','J','M','8','i','k',',','*','I','K','<','9','o','l',' ','.','(','O','L','>','0','p',';','/',')','P',':','?','-','[','\'','_','{','\"','=',']','\\','+','}','|' };

	//The constructor - Need to pass in timestamp and a hardkey
	public void init (String ts, String hk)
	{
        timeStamp = ts;
		hardKey = hk;
        transform= getGeneratedKey (list0.length);
	}

    //main - For testing purpose only
	public static void main(String[] args)
	{
		EbppxTransformer transformer = new EbppxTransformer();
		java.util.Date now = new java.util.Date();
		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat ("yyyyMMddHHmmss");
		//String ts=formatter.format(now);
		String ts="20110714115653";
		//String hardKey="MichaelCh$%^$^&&^an123Wwqa";
		String hardKey="X2q3j5k6E7r8l93tm2n7H5qp";

		// make sure list0 and list1 has 1 occurence of char each
		for (int i=0;i< transformer.list0.length ; i++ )
		{
			int occur=0;
			for (int j=0; j< transformer.list1.length ;  j++)
			{
				if (transformer.list0[i] == transformer.list1[j])
				{
					occur++;
				}
			}

			if (occur != 1)
			{
				System.out.println("Error="+ transformer.list0[i]);
			}
		}

// https://ebpsppweb.maxis.com.my/cus/SubmitLogon?timestamp=20110412124240&param=%3Dz%5F%5C%7C%3AP%5CSY%3DLK%2CL%28qL%2E%2C9J%2Em9H1m%2AM%280m%2Em94iKo%26mKlm%3BHUo%3CYYYYY
		String text="This is my message: 1-22238383,1-23737874,1-3434343-2323,sfsfsf#$F,34324,fbjhsf87344";
//20110714115653&param=z%7DW2%7Dwk9%5B%3B%2E%2E%299%2C%2F9%2D%3E%5D9%2D9%5BTL9%2D%2F9%29kC%2C4R5VrC%24V4kkkk
		System.out.println();
		System.out.println("====================transformer Algorithm=======================");
		System.out.println();
  		System.out.println("Pre Transform ="+text);
        String encrypted=transformer.encrypt(text, ts, hardKey);
		System.out.println("Hard key  ="+hardKey);
		System.out.println("Transformed  ="+encrypted);
		System.out.println("Detransformed ="+transformer.decrypt(encrypted,ts, hardKey));
		System.out.println("Detransformed: Meau ="+transformer.decrypt("z%7DW2%7Dwk9%5B%3B%2E%2E%299%2C%2F9%2D%3E%5D9%2D9%5BTL9%2D%2F9%29kC%2C4R5VrC%24V4kkkk",ts, hardKey));
		System.out.println();
		System.out.println("================================================================");
        System.out.println();


	}

	//This will generate the key or transform number base on timestamp and hardkey. The key is smaller than maxTransform
    private int getGeneratedKey (int maxTransform){
        int timeLength   = timeStamp.length();
        int keyLength    = hardKey.length();
        int rawKeyValue  = 0, timeValue   = 0, genKey    = 0;

        for (int i=0; i < keyLength; ++i) {
              rawKeyValue = rawKeyValue + hardKey.substring(i,i+1).hashCode();
              System.out.println("Raw value is.... "+rawKeyValue);
        }

		for (int i=0; i < timeLength; ++i) {
              timeValue = timeValue + timeStamp.substring(i,i+1).hashCode();
        }

		genKey = rawKeyValue + timeValue;


		if (genKey > maxTransform)
		{
			genKey = genKey % maxTransform;
		}

        return genKey;
    }

    //Encrypt the String and return the encrypted value
    public String encrypt (String inStr, String ts, String hk)
	{
		char[] inArray = inStr.toCharArray();
		char[] outArray = new char [inArray.length];
        int list0Index=-1;

		init(ts, hk);

		// for each char in input String
		for (int i=0;i< inArray.length ; i++ )
		{
           //check in list0
		   list0Index=-1;
		   for (int j=0; j< list0.length ; j++ )
           {
              if (inArray[i] == list0[j])
              {
				  list0Index =j;
              }
           }

		   // character not found
		   if (list0Index ==-1)
		   {
			   //no transformation
			   outArray[i] = inArray[i];
		   }
		   else
		   {
               int transPos=0;

			   if ( (list0Index+transform) < list0.length )
			   {
                   transPos = list0Index+transform;
			   }
			   else
			   {
                   transPos = (list0Index+transform) % list0.length;
			   }

               outArray[i] = list1[transPos];

		   }

		}
		return new String(outArray);

    }

    //Encrypt the String and return the encrypted value
    public String encrypt (String inStr)
	{
		char[] inArray = inStr.toCharArray();
		char[] outArray = new char [inArray.length];
        int list0Index=-1;

		// for each char in input String
		for (int i=0;i< inArray.length ; i++ )
		{
           //check in list0
		   list0Index=-1;
		   for (int j=0; j< list0.length ; j++ )
           {
              if (inArray[i] == list0[j])
              {
				  list0Index =j;
              }
           }

		   // character not found
		   if (list0Index ==-1)
		   {
			   //no transformation
			   outArray[i] = inArray[i];
		   }
		   else
		   {
               int transPos=0;

			   if ( (list0Index+transform) < list0.length )
			   {
                   transPos = list0Index+transform;
			   }
			   else
			   {
                   transPos = (list0Index+transform) % list0.length;
			   }

               outArray[i] = list1[transPos];

		   }

		}
		return new String(outArray);

    }

    //Decrypt the String and return the decrypted value
    public String decrypt(String inStr, String ts, String hk)
	{
		char[] inArray = inStr.toCharArray();
		char[] outArray = new char [inArray.length];
        int list1Index=-1;

		init(ts, hk);

		// for each char in input String
		for (int i=0;i< inArray.length ; i++ )
		{
           //check in list1
		   list1Index=-1;
		   for (int j=0; j< list1.length ; j++ )
           {
              if (inArray[i] == list1[j])
              {
				  list1Index =j;
              }
           }

		   // character not found
		   if (list1Index ==-1)
		   {
			   //no transformation
			   outArray[i] = inArray[i];
		   }
		   else
		   {
               int transPos=0;

			   if ( (list1Index + list1.length - transform ) >= list1.length )
			   {
                   transPos = list1Index-transform;
			   }
			   else
			   {
                   transPos = (list1Index + list1.length - transform);
			   }

               outArray[i] = list0[transPos];

		   }

		}
		return new String(outArray);
	}

    //Decrypt the String and return the decrypted value
    public String decrypt(String inStr)
	{
		char[] inArray = inStr.toCharArray();
		char[] outArray = new char [inArray.length];
        int list1Index=-1;

		// for each char in input String
		for (int i=0;i< inArray.length ; i++ )
		{
           //check in list1
		   list1Index=-1;
		   for (int j=0; j< list1.length ; j++ )
           {
              if (inArray[i] == list1[j])
              {
				  list1Index =j;
              }
           }

		   // character not found
		   if (list1Index ==-1)
		   {
			   //no transformation
			   outArray[i] = inArray[i];
		   }
		   else
		   {
               int transPos=0;

			   if ( (list1Index + list1.length - transform ) >= list1.length )
			   {
                   transPos = list1Index-transform;
			   }
			   else
			   {
                   transPos = (list1Index + list1.length - transform);
			   }

               outArray[i] = list0[transPos];

		   }

		}
		return new String(outArray);
	}
}